package com.itheima.health.web;


import com.alibaba.fastjson.JSON;
import com.itheima.health.entity.Result;
import com.itheima.health.pojo.User;
import com.itheima.health.service.AuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@WebFilter
@Slf4j
public class AuthFilter implements Filter {
    @Autowired
    private AuthService authService;

    //定义不需要登陆就放行的路径
    private static String[] loginCkUri = {
            //所有mobile端路径
            "/mobile/**",
            //登陆界面
            "/user/login",
            "/common/**"
    };

    //定义不需要登陆就放行的路径
    private static Map<String, String> uriPermissionMap = new HashMap<>();


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        //1.判断资源是否需要登陆权限
        String requestURI = request.getRequestURI();
        log.info("拦截路径:{}", requestURI);
        //1.1判断资源是否属于放行资源数组loginCkUri
        if (checkUri(requestURI, loginCkUri)) {
            //放行
            filterChain.doFilter(request, response);
            return;
        }
        //2.判断用户是否登录
        User user = (User) request.getSession().getAttribute("CURRENT_USER");
        if (user == null) {
            log.info("用户未登录");
            //重定向到登录页面 没找到前端跳转...?????
            Result notlogin = new Result(false,"NOTLOGIN");
            String notloginJson = JSON.toJSONString(notlogin);
            response.getWriter().write(notloginJson);
            return;
        }
        //3.判断资源是否需要角色权限
        if (!uriPermissionMap.containsKey(requestURI)) {
            //放行
            filterChain.doFilter(request, response);
            return;
        }
        //4.判断用户是否具有权限
        //4.1查询用户所具有的权限keywords
        List<String> userKeywords = authService.getUserKeywords(user.getId());
        log.info("用户的权限关键字:{}", userKeywords);
        //4.2查询用户用户是否有此路径需要的keyword
        String keyword = uriPermissionMap.get(requestURI);
        //4.3用户没有此权限
        if(!userKeywords.contains(keyword)){
            ServletOutputStream os = response.getOutputStream();
            Result result = new Result(false, "您没有该操作权限!");
            String string = JSON.toJSONString(result);
            os.write(string.getBytes());
            return;
        }
        //放行资源
        filterChain.doFilter(request, response);
    }


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        uriPermissionMap.put("/checkitem/add", "CHECKITEM_ADD");
        uriPermissionMap.put("/checkitem/delete", "CHECKITEM_DELETE");
        uriPermissionMap.put("/checkitem/edit", "CHECKITEM_EDIT");
        uriPermissionMap.put("/checkgroup/add", "CHECKGROUP_ADD");
        uriPermissionMap.put("/checkgroup/delete", "CHECKGROUP_DELETE");
        uriPermissionMap.put("/checkgroup/edit", "CHECKGROUP_EDIT");
        uriPermissionMap.put("/setmeal/add", "SETMEAL_ADD");
        uriPermissionMap.put("/setmeal/delete", "SETMEAL_DELETE");
        uriPermissionMap.put("/setmeal/edit", "SETMEAL_EDIT");
        uriPermissionMap.put("/report/getMemberReport", "REPORT_VIEW");
        uriPermissionMap.put("/report/getBusinessReportData", "REPORT_VIEW");
        uriPermissionMap.put("/report/exportBusinessReport", "REPORT_VIEW");

    }

    @Override
    public void destroy() {

    }


    /**
     * 判断请求路径是否属于某个放行路径数组
     *
     * @param requestUri
     * @param arr
     * @return
     */
    public static boolean checkUri(String requestUri, String[] arr) {
        //创建比较器
        AntPathMatcher apm = new AntPathMatcher();
        for (String allowedUri : arr) {
            if (apm.match(allowedUri, requestUri)) {
                return true;
            }
        }
        return false;
    }
}
